package cms.lucene;

import cms.bean.question.*;
import cms.service.question.QuestionIndexService;
import cms.service.question.QuestionService;
import cms.service.question.QuestionTagService;
import cms.utils.JsonUtils;
import com.fasterxml.jackson.core.type.TypeReference;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;

/**
 * 问题全文索引定时索引管理
 */
@Component("questionIndexManage")
public class QuestionIndexManage {
    private static final Logger logger = LogManager.getLogger(QuestionIndexManage.class);

    @Resource
    QuestionService questionService;
    @Resource
    QuestionIndexService questionIndexService;
    @Resource
    QuestionLuceneManage questionLuceneManage;
    @Resource
    CacheManager cacheManager;

    @Resource
    QuestionIndexManage questionIndexManage;
    @Resource
    QuestionTagService questionTagService;

    /**
     * 更新问题索引(由定时器触发)
     */
    public void updateQuestionIndex() {
        int firstindex = 0;//起始页
        int maxresult = 100;// 每页显示记录数

        if (!QuestionLuceneInit.INSTANCE.allowCreateIndexWriter()) {
            return;
        }


        try {
            QuestionLuceneInit.INSTANCE.createIndexWriter();//创建IndexWriter

            while (true) {
                //查询问题索引
                List<QuestionIndex> questionIndexList = questionIndexService.findQuestionIndex(firstindex, maxresult);


                if (questionIndexList == null || questionIndexList.size() == 0) {
                    break;
                }
                //添加问题Id集合
                Set<Long> add_questionIdList = new LinkedHashSet<Long>();
                //修改问题Id
                Set<Long> update_questionIdList = new LinkedHashSet<Long>();
                //删除问题Id
                Set<Long> delete_questionIdList = new LinkedHashSet<Long>();
                //删除用户名称
                Set<String> delete_userNameList = new LinkedHashSet<String>();

                List<Long> indexIdList = new ArrayList<Long>();
                for (QuestionIndex p : questionIndexList) {
                    indexIdList.add(p.getId());
                    if (p.getIndexState().equals(1)) {//1:添加
                        add_questionIdList.add(Long.parseLong(p.getDataId()));

                    } else if (p.getIndexState().equals(2)) {//2:修改
                        update_questionIdList.add(Long.parseLong(p.getDataId()));
                    } else if (p.getIndexState().equals(3)) {//3:删除
                        Long id = Long.parseLong(p.getDataId());
                        delete_questionIdList.add(id);

                        //删除添加和修改Id
                        add_questionIdList.remove(id);
                        update_questionIdList.remove(id);
                    } else if (p.getIndexState().equals(4)) {//4:删除用户发表的问题
                        delete_userNameList.add(p.getDataId());
                    }
                }

                //删除问题索引变化标记
                questionIndexService.deleteQuestionIndex(indexIdList);


                //查询问题Id集合
                Set<Long> questionIdList = new LinkedHashSet<Long>();
                questionIdList.addAll(add_questionIdList);
                questionIdList.addAll(update_questionIdList);

                //删除问题Id索引集合
                Set<Long> questionIdIndexList = new LinkedHashSet<Long>();
                questionIdIndexList.addAll(update_questionIdList);
                questionIdIndexList.addAll(delete_questionIdList);


                if (questionIdIndexList != null && questionIdIndexList.size() > 0) {
                    //删除当前Id索引
                    questionLuceneManage.deleteIndex(new ArrayList<Long>(questionIdIndexList));
                }

                //根据用户名称删除问题集合
                if (delete_userNameList != null && delete_userNameList.size() > 0) {
                    //删除用户名称下的索引
                    questionLuceneManage.deleteUserNameIndex(new ArrayList<String>(delete_userNameList));
                }

                if (questionIdList != null && questionIdList.size() > 0) {
                    //根据问题Id集合查询问题
                    List<Question> questionList = questionService.findQuestionByQuestionIdList(new ArrayList<Long>(questionIdList));
                    if (questionList != null && questionList.size() > 0) {

                        List<QuestionTag> questionTagList = questionTagService.findAllQuestionTag();

                        if (questionTagList != null && questionTagList.size() > 0) {
                            for (Question question : questionList) {
                                //删除最后一个逗号
                                String _appendContent = StringUtils.substringBeforeLast(question.getAppendContent(), ",");//从右往左截取到相等的字符,保留左边的

                                List<AppendQuestionItem> appendQuestionItemList = JsonUtils.toGenericObject(_appendContent + "]", new TypeReference<List<AppendQuestionItem>>() {
                                });
                                question.setAppendQuestionItemList(appendQuestionItemList);

                                Map<Long,QuestionTagAssociation> questionTagAssociationMap = questionService.findQuestionTagAssociationByQuestionId(question.getId());
                                if(MapUtils.isNotEmpty(questionTagAssociationMap)){
                                    for (QuestionTag questionTag : questionTagList) {
                                        QuestionTagAssociation questionTagAssociation = questionTagAssociationMap.get(questionTag.getId());
                                        questionTagAssociation.setQuestionTagName(questionTag.getName());
                                        question.addQuestionTagAssociation(questionTagAssociation);
//                                        for (QuestionTagAssociation questionTagAssociation : questionTagAssociationList) {
//                                            if (questionTagAssociation.getQuestionTagId().equals(questionTag.getId())) {
//                                                questionTagAssociation.setQuestionTagName(questionTag.getName());
//                                                question.addQuestionTagAssociation(questionTagAssociation);
//                                                break;
//                                            }
//                                        }
                                    }
                                }
                            }
                        }
                        //写入索引
                        questionLuceneManage.addIndex(questionList);

                    }
                }


            }
        } catch (Exception e) {

            //	e.printStackTrace();
            if (logger.isErrorEnabled()) {
                logger.error("更新问题索引(由定时器触发)", e);
            }
        } finally {
            QuestionLuceneInit.INSTANCE.closeIndexWriter();//关闭IndexWriter
        }
    }

    /**
     * 添加全部问题索引
     */
    public void addAllQuestionIndex() {
        long count = 0;
        int page = 1;//分页 当前页
        int maxresult = 200;// 每页显示记录数

        questionIndexManage.taskRunMark_delete();
        questionIndexManage.taskRunMark_add(count);


        boolean allow = QuestionLuceneInit.INSTANCE.allowCreateIndexWriter();//是否允许创建IndexWriter
        if (allow) {
            //删除所有问题索引变化标记
            questionIndexService.deleteAllIndex();

            try {
                QuestionLuceneInit.INSTANCE.createIndexWriter();//创建IndexWriter

                questionLuceneManage.deleteAllIndex();//删除所有索引


                while (true) {
                    count++;
                    questionIndexManage.taskRunMark_delete();
                    questionIndexManage.taskRunMark_add(count);

                    //当前页
                    int firstindex = (page - 1) * maxresult;
                    //查询问题
                    List<Question> questionList = questionService.findQuestionByPage(firstindex, maxresult);

                    if (questionList == null || questionList.size() == 0) {
                        break;
                    }


                    List<QuestionTag> questionTagList = questionTagService.findAllQuestionTag();

                    if (questionTagList != null && questionTagList.size() > 0) {
                        for (Question question : questionList) {
                            //删除最后一个逗号
                            String _appendContent = StringUtils.substringBeforeLast(question.getAppendContent(), ",");//从右往左截取到相等的字符,保留左边的

                            List<AppendQuestionItem> appendQuestionItemList = JsonUtils.toGenericObject(_appendContent + "]", new TypeReference<List<AppendQuestionItem>>() {
                            });
                            question.setAppendQuestionItemList(appendQuestionItemList);


                            Map<Long,QuestionTagAssociation> questionTagAssociationMap = questionService.findQuestionTagAssociationByQuestionId(question.getId());
                            if(MapUtils.isNotEmpty(questionTagAssociationMap)){
                                for (QuestionTag questionTag : questionTagList) {
                                    QuestionTagAssociation questionTagAssociation = questionTagAssociationMap.get(questionTag.getId());
                                    questionTagAssociation.setQuestionTagName(questionTag.getName());
                                    question.addQuestionTagAssociation(questionTagAssociation);
//                                    for (QuestionTagAssociation questionTagAssociation : questionTagAssociationList) {
//                                        if (questionTagAssociation.getQuestionTagId().equals(questionTag.getId())) {
//                                            questionTagAssociation.setQuestionTagName(questionTag.getName());
//                                            question.addQuestionTagAssociation(questionTagAssociation);
//                                            break;
//                                        }
//                                    }
                                }
                            }
                        }
                    }


                    //写入索引
                    questionLuceneManage.addIndex(questionList);
                    page++;
                }
            } catch (Exception e) {

                //	e.printStackTrace();
                if (logger.isErrorEnabled()) {
                    logger.error("添加全部问题索引", e);
                }
            } finally {
                QuestionLuceneInit.INSTANCE.closeIndexWriter();//关闭IndexWriter
            }
        }

        questionIndexManage.taskRunMark_delete();
    }


    /**
     * 查询/添加任务运行标记
     *
     * @param count 次数  -1为查询方式
     * @return
     */
    @Cacheable(value = "questionIndexManage_cache_taskRunMark", key = "'taskRunMark'")
    public Long taskRunMark_add(Long count) {
        return count;
    }

    /**
     * 删除任务运行标记
     *
     * @return
     */
    @CacheEvict(value = "questionIndexManage_cache_taskRunMark", key = "'taskRunMark'")
    public void taskRunMark_delete() {
    }


    /**
     * 定时刷新本地索引(20秒)
     */
    @Scheduled(fixedDelay = 20000)
    public void refreshIndex() {
        QuestionLuceneInit.INSTANCE.refreshSearcher();
    }


}
